// Key Mover Animator
// (c) jimon game studio

#ifndef JEH_JEKEYMOVERANIMATOR
#define JEH_JEKEYMOVERANIMATOR

#include "ISceneManager.h"
#include "IAnimator.h"
#include "jeInputController.h"
#include "IFpsCounter.h"

namespace je
{
	namespace scene
	{
		//! Key Mover Animator
		class jeKeyMoverAnimator:public je::scene::IAnimator
		{
		private:
			device::IWindow * Window;
			input::jeInputController * In_Forward;
			input::jeInputController * In_Back;
			input::jeInputController * In_Left;
			input::jeInputController * In_Right;

			jeVector3df Foward;
			jeVector3df Right;

			f32 Speed;

			u1 NoYawMoving;
		public:
			//! Constructor
			jeKeyMoverAnimator(ISceneManager * SceneManager)
				:IAnimator("KeyMoverAnimator"),In_Forward(NULL),In_Back(NULL),In_Left(NULL),In_Right(NULL),Speed(0.05f),NoYawMoving(false)
			{
				Window = SceneManager->GetRender()->GetContext()->GetWindow();

				MapKeys(input::KC_W,input::KC_S,input::KC_A,input::KC_D);

				Foward.SetXYZ(0,0,1);
				Right.SetXYZ(-1,0,0);
			}

			//! Desturctor
			~jeKeyMoverAnimator()
			{
				MapKeys(input::KC_NULL,input::KC_NULL,input::KC_NULL,input::KC_NULL);
			}

			//! Update Controller
			void OnUpdate()
			{
				jeVector3df Moving;

				if(In_Forward && In_Forward->IsDown())
					Moving -= (Foward * Speed * JEDT32);

				if(In_Back && In_Back->IsDown())
					Moving += (Foward * Speed * JEDT32);

				if(In_Right && In_Right->IsDown())
					Moving -= (Right * Speed * JEDT32);

				if(In_Left && In_Left->IsDown())
					Moving += (Right * Speed * JEDT32);


				jeMatrix4f Mat;
				if(NoYawMoving)
					Mat.Rotate(jeVector3df(0,ParentNode->GetRotation().Y,0));
				else
					Mat.Rotate(ParentNode->GetRotation());
				Moving = Mat.MultiplyVectorOnMatrix(Moving);

				ParentNode->SetPosition(Moving,true);

				IAnimator::OnUpdate();
			}

			//! Map Keys
			void MapKeys(input::KeyCode Forward,input::KeyCode Back,input::KeyCode Left,input::KeyCode Right)
			{
				if(In_Forward)
				{
					JEDELETE(In_Forward)
					In_Forward = NULL;
				}
				if(Forward > input::KC_NULL)
					JENEW(In_Forward,input::jeInputController(Forward,Window->GetKeyDriver()))

				if(In_Back)
				{
					JEDELETE(In_Back)
					In_Back = NULL;
				}
				if(Back > input::KC_NULL)
					JENEW(In_Back,input::jeInputController(Back,Window->GetKeyDriver()))

				if(In_Left)
				{
					JEDELETE(In_Left)
					In_Left = NULL;
				}
				if(Left > input::KC_NULL)
					JENEW(In_Left,input::jeInputController(Left,Window->GetKeyDriver()))

				if(In_Right)
				{
					JEDELETE(In_Right)
					In_Right = NULL;
				}
				if(Right > input::KC_NULL)
					JENEW(In_Right,input::jeInputController(Right,Window->GetKeyDriver()))
			}

			//! Set No Yaw Moving
			void SetNoYawMoving(u1 Enable)
			{
				NoYawMoving = Enable;
			}

			//! Serialize
			void Serialize(core::ISerializeStream * SerializeStream)
			{
				JE_SS_BEGIN(KeyMoverAnimator)
				JE_SS(NoYawMoving)

				input::KeyCode Forward,Back,Left,Right;
				if(JE_SS_SAVE)
				{
					Forward = In_Forward->GetKey();
					Back = In_Back->GetKey();
					Left = In_Left->GetKey();
					Right = In_Right->GetKey();
				}

				JE_SS_ENUM(Forward,input::KeyCode)
				JE_SS_ENUM(Back,input::KeyCode)
				JE_SS_ENUM(Left,input::KeyCode)
				JE_SS_ENUM(Right,input::KeyCode)

				JE_SS_END(KeyMoverAnimator)

				if(JE_SS_LOAD)
					MapKeys(Forward,Back,Left,Right);

				IAnimator::Serialize(SerializeStream);
			}
		};
	}
}

#endif
